package com.mg.plugin.agrometeorology.common;

import com.mg.model.Model;
import com.mg.plugin.agrometeorology.entity.StationData;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

public class OstriniaNubilalisCalculator {

    private static final int DJ = 1;
    private static final int MAY = 5;
    private static final int JUNE = 6;
    private static final int JUNE1 = 61;
    private static final int JUNE2 = 62;
    private static final int JUNE3 = 63;
    private static final int JUNE_SP = 64;
    private static final int JULY1 = 71;
    private static final int JULY2 = 72;
    private static final int JULY3 = 73;
    private static final int JUNE_SGP = 600;
    private static final int JULY_SGP1 = 701;
    private static final int JULY_SGP2 = 702;
    private static final int AUG_SGP = 800;

    public static float calcDisasterLevel(List<StationData> stationDatas, String m_strBeginDate, Model model) throws ParseException {
        StationData stationData = stationDatas.get(0);
        float lat = stationData.getLat();
        float lon = stationData.getLon();
        boolean isSec = false;
        if (lat > 42.43 && lon < 125.36) {
            isSec = true;
        }
        List<String> djData = new ArrayList<String>();
        List<String> mayData = new ArrayList<String>();
        List<String> june1Data = new ArrayList<String>();
        List<String> june2Data = new ArrayList<String>();
        List<String> june3Data = new ArrayList<String>();
        List<String> july1Data = new ArrayList<String>();
        List<String> july2Data = new ArrayList<String>();
        List<String> july3Data = new ArrayList<String>();
        List<String> aug1Data = new ArrayList<String>();
//WINTERING|RECOVERY|PHLEGM|FEATHERING|INCUBATION|LARVAL|FGP|SGP
        //数据分类
        assistData(djData, mayData, june1Data, june2Data, june3Data, july1Data, july2Data, july3Data, aug1Data, stationDatas);
        if ("WINTERING".equalsIgnoreCase(m_strBeginDate)) {
            //越冬期
            return calcWinteringPeriod(model, djData);
        }

        if ("RECOVERY".equalsIgnoreCase(m_strBeginDate)) {
            //复苏期
            return calcRecoveryPeriod(model, mayData, june1Data);
        }

        if ("PHLEGM".equalsIgnoreCase(m_strBeginDate)) {
            //化蛹期
            return calcPhlegmPhase(model, june1Data, june2Data, june3Data, july1Data, isSec);
        }
        if ("FEATHERING".equalsIgnoreCase(m_strBeginDate)) {
            //羽化期
            return calcFeatheringPeriod(model, june2Data, june3Data, july1Data, isSec);
        }
        if ("INCUBATION".equalsIgnoreCase(m_strBeginDate)) {
            //孵化期
            return calcIncubationPeriod(model, june3Data, july1Data, july2Data, isSec);
        }
        if ("LARVAL".equalsIgnoreCase(m_strBeginDate)) {
            //幼虫期
            return calcLarvalStage(model, july1Data, july2Data, july3Data, isSec);
        }
        if ("FGP".equalsIgnoreCase(m_strBeginDate)) {

            List<String> juneData = new ArrayList<String>();
            juneData.addAll(june1Data);
            juneData.addAll(june2Data);
            juneData.addAll(june3Data);
            //一代全发育期
            return calcFirstGrowthPeriod(model, djData, mayData, juneData, july1Data);
        }
        if ("SGP".equalsIgnoreCase(m_strBeginDate)) {
            //二代全发育期
            return calcSecondGrowthPeriod(model, june3Data, july1Data, july2Data, july3Data, aug1Data);
        }


        return 0;
    }

    /**
     * 二代全发育期
     *
     * @param model
     * @param june3Data
     * @param july1Data
     * @param july2Data
     * @param july3Data
     * @param aug1Data
     * @return
     */
    private static float calcSecondGrowthPeriod(Model model, List<String> june3Data, List<String> july1Data, List<String> july2Data, List<String> july3Data, List<String> aug1Data) {
        List<String> data = new ArrayList<String>();
        int g1 = 0, g2 = 0, g3 = 0, g4 = 0;

        int conMin = 0;
        int tmp = 0;

        data.addAll(june3Data);
        data.addAll(july1Data);
        float grJune = calcRain(data, JUNE_SGP, model);
        if (grJune < 41) {
            g1++;
            tmp++;
        }

        data.clear();
        data.addAll(july1Data);
        data.addAll(july2Data);
        float grJuly1 = calcRain(data, JULY_SGP1, model);
        if (grJuly1 < 41) {
            g2++;
            tmp++;
        } else {
            if (tmp > conMin) {
                conMin = tmp;
                tmp = 0;
            }
        }

        data.clear();
        data.addAll(july2Data);
        data.addAll(june3Data);
        float grJuly2 = calcRain(data, JULY_SGP2, model);
        if (grJuly2 < 41) {
            g3++;
            tmp++;
        } else {
            if (tmp > conMin) {
                conMin = tmp;
                tmp = 0;
            }
        }

        data.clear();
        data.addAll(june3Data);
        data.addAll(aug1Data);
        float grAug = calcRain(data, AUG_SGP, model);
        if (grAug < 41) {
            g4++;
            tmp++;
        }
        if (tmp > conMin) {
            conMin = tmp;
        }
        float level = 0;
        if (conMin >= 2) {
            level = 19;
        } else {
            int total = g1 + g2 + g3 + g4;
            if (total == 1) {
                level = (g1 + 1) * 0.2f * grJune + (g2 + 1) * 0.2f * grJuly1 + (g3 + 1) * 0.2f * grJuly2 + (g4 + 1) * 0.2f * grAug;
            } else if (total == 2) {
                level = (g1 * 0.2f + 0.15f) * grJune + (g2 * 0.2f + 0.15f) * grJuly1 + (g3 * 0.2f + 0.15f) * grJuly2 + (g4 * 0.2f + 0.15f) * grAug;
            } else {
                level = (grJune + grJuly1 + grJuly2 + grAug) * 0.25f;
            }

        }
        model.OutputLog(Model.LogLevel.Info, "calcSecondGrowthPeriod:grJune=" + grJune
                + "grJuly1=" + grJuly1 + "grJuly2=" + grJuly2 + "grAug=" + grAug + "LEVEL=" + level);
        return level;
    }

    /**
     * 一代全发育期
     *
     * @param model
     * @param djData
     * @param mayData
     * @param juneData
     * @param july1Data
     * @return
     */
    private static float calcFirstGrowthPeriod(Model model, List<String> djData, List<String> mayData, List<String> juneData, List<String> july1Data) {
        float gtDJ = calcAvgTemp(djData, DJ, model);
        float gtMay = calcAvgTemp(mayData, MAY, model);
        float grMay = calcRain(mayData, MAY, model);
        float grJune = calcRain(juneData, JUNE, model);
        float gwtJuly = calcWTemp(july1Data, model);
        float level = gtDJ * 0.20f + gtMay * 0.21f + grMay * 0.21f + grJune * 0.18f + gwtJuly * 0.20f;
        model.OutputLog(Model.LogLevel.Info, "calcFirstGrowthPeriod:gtDJ=" + gtDJ
                + "gtMay=" + gtMay + "grMay=" + grMay + "grJune=" + grJune + "gwtJuly"
                + gwtJuly + "LEVEL=" + level);
        return level;
    }

    /**
     * 幼虫期
     *
     * @param model
     * @param july1Data
     * @param july2Data
     * @param july3Data
     * @param isSec
     * @return
     */
    private static float calcLarvalStage(Model model, List<String> july1Data, List<String> july2Data, List<String> july3Data, boolean isSec) {

        float grJuly2 = calcRain(july2Data, JULY2, model);
        float ghJuly2 = calcHumidity(july2Data, JULY2, model);
        float gnJuly2 = calcRainstorm(july2Data, JULY2, model);

        if (isSec) {
            float grJuly1 = calcRain(july1Data, JULY1, model);
            float ghJuly1 = calcHumidity(july1Data, JULY1, model);
            float gnJuly1 = calcRainstorm(july1Data, JULY1, model);
            float level = gnJuly1 * 0.2f + (grJuly1 + ghJuly1 + grJuly2 + ghJuly2 + gnJuly2) * 0.16f;
            model.OutputLog(Model.LogLevel.Info, "calcLarvalStage:gnJuly1=" + gnJuly1
                    + "grJuly1=" + grJuly1 + "gnJuly2=" + gnJuly2 + "ghJuly1=" + ghJuly1 + "ghJuly2"
                    + ghJuly2 + "grJuly2" + grJuly2 + "LEVEL=" + level);
            return level;
        }

        float grJuly3 = calcRain(july3Data, JULY3, model);
        float ghJuly3 = calcHumidity(july3Data, JULY3, model);
        float gnJuly3 = calcRainstorm(july3Data, JULY3, model);
        float level = gnJuly2 * 0.2f + (grJuly2 + ghJuly2 + grJuly3 + ghJuly3 + gnJuly3) * 0.16f;
        model.OutputLog(Model.LogLevel.Info, "calcLarvalStage:ghJuly3=" + ghJuly3
                + "grJuly3=" + grJuly3 + "gnJuly2=" + gnJuly2 + "gnJuly3=" + gnJuly3 + "ghJuly2"
                + ghJuly2 + "grJuly2" + grJuly2 + "LEVEL=" + level);
        return level;
    }

    /**
     * 孵化期
     *
     * @param model
     * @param june3Data
     * @param july1Data
     * @param july2Data
     * @param isSec
     * @return
     */
    private static float calcIncubationPeriod(Model model, List<String> june3Data, List<String> july1Data, List<String> july2Data, boolean isSec) {

        float grJuly1 = calcRain(july1Data, JULY1, model);
        float ghJuly1 = calcHumidity(july1Data, JULY1, model);

        if (isSec) {
            float grJune3 = calcRain(june3Data, JUNE3, model);
            float ghJune3 = calcHumidity(june3Data, JUNE3, model);
            float level = (grJune3 + grJuly1 + ghJune3 + ghJuly1) * 0.25f;
            model.OutputLog(Model.LogLevel.Info, "calcIncubationPeriod:grJune3=" + grJune3
                    + "grJuly1=" + grJuly1 + "ghJune3=" + ghJune3 + "ghJuly1=" + ghJuly1 + "LEVEL=" + level);
            return level;
        }
        float grJuly2 = calcRain(july2Data, JULY2, model);
        float ghJuly2 = calcHumidity(july2Data, JULY2, model);
        float level = (grJuly2 + grJuly1 + ghJuly2 + ghJuly1) * 0.25f;
        model.OutputLog(Model.LogLevel.Info, "calcIncubationPeriod:grJuly2=" + grJuly2
                + "grJuly1=" + grJuly1 + "ghJuly2=" + ghJuly2 + "ghJuly1=" + ghJuly1 + "LEVEL=" + level);
        return level;
    }

    /**
     * 羽化期
     *
     * @param model
     * @param june2Data
     * @param june3Data
     * @param july1Data
     * @param isSec
     * @return
     */
    private static float calcFeatheringPeriod(Model model, List<String> june2Data, List<String> june3Data, List<String> july1Data, boolean isSec) {
        float gtgJune3 = calcAvgTmax(june3Data, JUNE3, model);
        float grJune3 = calcRain(june3Data, JUNE3, model);
        float ghJune3 = calcHumidity(june3Data, JUNE3, model);

        if (isSec) {
            List<String> juneData = new ArrayList<String>();
            juneData.addAll(june2Data);
            juneData.addAll(june3Data);
            float ghJune2 = calcHumidity(june2Data, JUNE2, model);
            float gtgJune2 = calcAvgTmax(june2Data, JUNE2, model);
            float grJune2 = calcRain(june2Data, JUNE2, model);
            float gnJune = calcRainstorm(juneData, JUNE, model);

            float level = gnJune * 0.1f + grJune2 * 0.15f + grJune3 * 0.15f + gtgJune2 * 0.15f + gtgJune3 * 0.15f + ghJune2 * 0.15f + ghJune3 * 0.15f;
            model.OutputLog(Model.LogLevel.Info, "calcFeatheringPeriod:gnJune=" + gnJune
                    + "grJune2=" + grJune2 + "grJune3=" + grJune3 + "gtgJune2=" + gtgJune2
                    + "gtgJune3=" + gtgJune3 + "ghJune2=" + ghJune2 + "ghJune3=" + ghJune3 + "LEVEL=" + level);
            return level;
        }

        List<String> julyData = new ArrayList<String>();
        julyData.addAll(june3Data);
        julyData.addAll(july1Data);
        float gnJuly = calcRainstorm(julyData, JUNE, model);
        float ghJuly1 = calcHumidity(july1Data, JULY1, model);
        float grJuly1 = calcRain(july1Data, JULY1, model);
        float gtgJuly1 = calcAvgTmax(july1Data, JULY1, model);
        float level = gnJuly * 0.1f + grJune3 * 0.15f + grJuly1 * 0.15f + gtgJune3 * 0.15f + gtgJuly1 * 0.15f + ghJune3 * 0.15f + ghJuly1 * 0.15f;
        model.OutputLog(Model.LogLevel.Info, "calcFeatheringPeriod:gnJuly=" + gnJuly
                + "grJuly1=" + grJuly1 + "grJune3=" + grJune3 + "gtgJuly1=" + gtgJuly1
                + "gtgJune3=" + gtgJune3 + "ghJuly1=" + ghJuly1 + "ghJune3=" + ghJune3 + "LEVEL=" + level);
        return level;
    }


    /**
     * 化蛹期
     *
     * @param model
     * @param june1Data
     * @param june2Data
     * @param june3Data
     * @param july1Data
     * @param isSec
     * @return
     */
    private static float calcPhlegmPhase(Model model, List<String> june1Data, List<String> june2Data, List<String> june3Data, List<String> july1Data, boolean isSec) {

        //六月中降水等级
        float grPPJune2 = calcRain(june2Data, JUNE2, model);
        //六月中相对湿度等级
        float ghPPJune2 = calcHumidity(june2Data, JUNE_SP, model);
        //六月下降水等级
        float grPPJune3 = calcRain(june3Data, JUNE3, model);
        //六月下相对湿度等级
        float ghPPJune3 = calcHumidity(june3Data, JUNE_SP, model);
        if (isSec) {
            //六月上降水等级
            float grPPJune1 = calcRain(june1Data, JUNE1, model);
            //六月上相对湿度等级
            float ghPPJune1 = calcHumidity(june1Data, JUNE_SP, model);
            float level = (grPPJune1 + grPPJune2 + grPPJune3 + ghPPJune3) * 0.17f + (ghPPJune1 + ghPPJune2) * 0.16f;
            model.OutputLog(Model.LogLevel.Info, "calcPhlegmPhase:grPPJune1=" + grPPJune1
                    + "grPPJune2=" + grPPJune2 + "grPPJune3=" + grPPJune3 + "ghPPJune3=" + ghPPJune3
                    + "ghPPJune1=" + ghPPJune1 + "ghPPJune2" + ghPPJune2 + "LEVEL=" + level);
            return level;
        }
        //七月上降水等级
        float grPPJuly1 = calcRain(july1Data, JULY1, model);
        //七月上相对湿度等级
        float ghPPJuly1 = calcHumidity(july1Data, JULY1, model);
        float level = (grPPJune2 + grPPJune3 + grPPJuly1 + ghPPJuly1) * 0.17f + (ghPPJune2 + ghPPJune3) * 0.16f;
        model.OutputLog(Model.LogLevel.Info, "calcPhlegmPhase:grPPJuly1=" + grPPJuly1
                + "grPPJune2=" + grPPJune2 + "grPPJune3=" + grPPJune3 + "ghPPJune3=" + ghPPJune3
                + "ghPPJuly1=" + ghPPJuly1 + "ghPPJune2" + ghPPJune2 + "LEVEL=" + level);
        return level;
    }

    /**
     * 复苏期
     *
     * @param model
     * @param mayData
     * @param june1Data
     * @return
     */
    private static float calcRecoveryPeriod(Model model, List<String> mayData, List<String> june1Data) {
        //五月平均气温等级
        float gtRPMay = calcAvgTemp(mayData, MAY, model);
        //五月累积降水等级
        float grRPMay = calcRain(mayData, MAY, model);
        //六月上降水等级
        float grRPJune1 = calcRain(june1Data, JUNE1, model);
        //六月上相对湿度等级
        float ghRPJune1 = calcHumidity(june1Data, JUNE1, model);
        float level = (gtRPMay + grRPMay + grRPJune1) * 0.3f + ghRPJune1 * 0.1f;
        model.OutputLog(Model.LogLevel.Info, "calcRecoveryPeriod:AVG_TMP_MAY=" + gtRPMay
                + "ACC_RAIN_MAY=" + grRPMay + "ACC_RAIN_JUNE=" + grRPJune1 + "RH_JUNE=" + ghRPJune1 + "LEVEL=" + level);
        return level;
    }

    /**
     * 越冬期
     *
     * @param model
     * @param djData
     * @return
     */
    private static float calcWinteringPeriod(Model model, List<String> djData) {
        //冬季平均气温等级
        float gtWPDJ = calcAvgTemp(djData, DJ, model);
        //冬季累积降水等级
        float grWPDJ = calcRain(djData, DJ, model);
        //冬季相对湿度等级
        float ghWPDJ = calcHumidity(djData, DJ, model);
        float level = gtWPDJ * 0.34f + grWPDJ * 0.34f + ghWPDJ * 0.32f;
        model.OutputLog(Model.LogLevel.Info, "calcWinteringPeriod:AVG_TMP_WINTER=" + gtWPDJ
                + "ACC_RAIN_WINTER=" + grWPDJ + "RH_WINTER=" + ghWPDJ + "LEVEL=" + level);
        return level;
    }

    /**
     * 计算温度适宜度等级
     *
     * @param dataList
     * @param month
     * @param model
     * @return
     */
    private static float calcAvgTmax(List<String> dataList, int month, Model model) {
        float total = 0;
        for (String tmp : dataList) {
            total += Float.parseFloat(tmp.split(",")[1]);
        }
        float temp = total / dataList.size();
        if (temp <= 22.0f) {
            return 20;
        }
        if (temp <= 23.0f) {
            return 21 + (temp - 22.0f) / (1.0f / 20.0f);
        }
        if (temp <= 24.0f) {
            return 41 + (temp - 23.0f) / (1.0f / 20.0f);
        }
        if (temp <= 25.0f) {
            return 61 + (temp - 24.0f) / (1.0f / 20.0f);
        }
        if (temp <= 26.0f) {
            return 81 + (temp - 25.0f) / (1.0f / 20.0f);
        }
        if (temp <= 28.0f) {
            return 81 + (temp - 26.0f) / (1.0f / 20.0f);
        }
        if (temp <= 30.0f) {
            return 61 + (temp - 28.0f) / (1.0f / 20.0f);
        }
        if (temp <= 32.0f) {
            return 41 + (temp - 30.0f) / (1.0f / 20.0f);
        }
        if (temp <= 33.0f) {
            return 21 + (temp - 32.0f) / (1.0f / 20.0f);
        }
        return 20;

    }

    /**
     * 计算暴雨日等级
     *
     * @param dataList
     * @param month
     * @param model
     * @return
     */
    private static float calcRainstorm(List<String> dataList, int month, Model model) {
        float count = 0;
        for (String tmp : dataList) {
            if (Float.parseFloat(tmp.split(",")[2]) > 50) {
                count++;
            }
        }
        if (count >= 3) {
            return 20;
        }
        if (count == 2) {
            return 30;
        }
        if (count == 1) {
            return 50;
        }
        return 80;
    }

    /**
     * 计算相对湿度等级
     *
     * @param dataList
     * @param month
     * @param model
     * @return
     */
    private static float calcHumidity(List<String> dataList, int month, Model model) {

        float total = 0;
        for (String tmp : dataList) {
            total += Float.parseFloat(tmp.split(",")[3]);
        }
        float humi = total / dataList.size();
        if (month == DJ) {
            return 100 - humi;
        }
        if (month == JUNE_SP) {
            if (humi <= 40) {
                return humi;
            }
            if (humi <= 50.0) {
                return 41 + (humi - 40.0f) / ((50.0f - 40.0f) / 20);
            }
            if (humi <= 60.0) {
                return 61 + (humi - 50.0f) / ((60.0f - 50.0f) / 20);
            }
            if (humi <= 80.0) {
                return 81 + (humi - 60.0f) / ((80.0f - 60.0f) / 20);
            }
            return 61 + (humi - 80.0f) / ((100.0f - 80.0f) / 20);
        }
        return humi;
    }

    /**
     * 计算水热系数
     *
     * @param dataList
     * @param model
     * @return
     */
    private static float calcWTemp(List<String> dataList, Model model) {
        float totalRain = 0;
        float totalTmp = 0;
        for (String tmp : dataList) {
            totalRain += Float.parseFloat(tmp.split(",")[0]);
            totalTmp += Float.parseFloat(tmp.split(",")[1]);
        }
        float WTemp = 0;
        if (totalTmp != 0) {
            WTemp = totalRain / (totalTmp / dataList.size());
        }
        model.OutputLog(Model.LogLevel.Info, "WTemp:" + WTemp + "totalRain:" + totalRain + "totalTmp:" + totalTmp);
        if (WTemp < 0.5) {
            return 20;
        }
        if (WTemp <= 1.2) {
            return 21 + (WTemp - 0.5f) / ((1.2f - 0.5f) / 20);
        }
        if (WTemp <= 3.4) {
            return 41 + (WTemp - 1.3f) / ((3.4f - 1.3f) / 20);
        }
        if (WTemp <= 5.0) {
            return 60 + (WTemp - 3.5f) / ((5.0f - 3.5f) / 20);
        }
        return 100;
    }

    /**
     * 计算降水等级
     *
     * @param dataList
     * @param june
     * @param model
     * @return
     */
    private static float calcRain(List<String> dataList, int june, Model model) {
        float total = 0;
        for (String tmp : dataList) {
            total += Float.parseFloat(tmp.split(",")[2]);
        }
        if (june == DJ) {
            if (total <= 19.7) {
                return 20;
            }
            if (total <= 28.9) {
                return 21 + (total - 19.7f) / ((28.9f - 19.7f) / 20);
            }
            if (total <= 38.0) {
                return 41 + (total - 28.9f) / ((38.0f - 28.9f) / 20);
            }
            if (total <= 44.2) {
                return 61 + (total - 38.0f) / ((44.2f - 38.0f) / 20);
            }
            return 100;
        }
        if (june == MAY) {
            if (total < 22.3) {
                return 20;
            }
            if (total <= 28.8) {
                return 21 + (total - 22.3f) / ((28.8f - 22.3f) / 20);
            }
            if (total <= 45.6) {
                return 41 + (total - 28.9f) / ((45.6f - 28.9f) / 20);
            }
            if (total <= 67.8) {
                return 61 + (total - 45.7f) / ((67.8f - 45.7f) / 20);
            }
            return 100;
        }
        if (june == JUNE) {
            if (total < 46.2) {
                return 20;
            }
            if (total <= 65.0) {
                return 21 + (total - 46.2f) / ((65.0f - 46.2f) / 20);
            }
            if (total <= 80.0) {
                return 41 + (total - 65.0f) / ((80.0f - 65.0f) / 20);
            }
            if (total <= 100.0) {
                return 61 + (total - 80.0f) / ((100.0f - 80.0f) / 20);
            }
            return 100;
        }
        if (june == JUNE1) {
            if (total < 0) {
                return 20;
            }
            if (total <= 10.3) {
                return 21 + (total - 0f) / ((10.3f - 0f) / 20);
            }
            if (total <= 18.0) {
                return 41 + (total - 10.3f) / ((18.0f - 10.3f) / 20);
            }
            if (total <= 25.7) {
                return 61 + (total - 18.0f) / ((25.7f - 18.0f) / 20);
            }
            if (total <= 33.4) {
                return 81 + (total - 25.7f) / ((33.4f - 25.7f) / 20);
            }
            if (total <= 41.1) {
                return 81 + (total - 33.4f) / ((41.1f - 33.4f) / 20);
            }
            if (total <= 51.4) {
                return 61 + (total - 41.1f) / ((51.4f - 41.1f) / 20);
            }
            return 60;
        }
        if (june == JUNE2) {
            if (total < 0) {
                return 20;
            }
            if (total <= 11.0) {
                return 21 + (total - 0f) / ((11.0f - 0f) / 20);
            }
            if (total <= 19.3) {
                return 41 + (total - 11.0f) / ((19.3f - 11.0f) / 20);
            }
            if (total <= 27.5) {
                return 61 + (total - 19.3f) / ((27.5f - 19.3f) / 20);
            }
            if (total <= 35.8) {
                return 81 + (total - 27.5f) / ((35.8f - 27.5f) / 20);
            }
            if (total <= 44.0) {
                return 81 + (total - 35.8f) / ((44.0f - 35.8f) / 20);
            }
            if (total <= 55.0) {
                return 61 + (total - 44.0f) / ((55.0f - 44.0f) / 20);
            }
            return 60;
        }
        if (june == JUNE3) {
            if (total < 0) {
                return 20;
            }
            if (total <= 13.9) {
                return 21 + (total - 0f) / ((13.9f - 0f) / 20);
            }
            if (total <= 24.4) {
                return 41 + (total - 13.9f) / ((24.4f - 13.9f) / 20);
            }
            if (total <= 34.8) {
                return 61 + (total - 24.4f) / ((34.8f - 24.4f) / 20);
            }
            if (total <= 45.2) {
                return 81 + (total - 34.8f) / ((45.2f - 34.8f) / 20);
            }
            if (total <= 55.7) {
                return 81 + (total - 45.2f) / ((55.7f - 45.2f) / 20);
            }
            if (total <= 69.6) {
                return 61 + (total - 55.7f) / ((69.6f - 55.7f) / 20);
            }
            return 60;
        }
        if (june == JULY1) {
            if (total < 0) {
                return 20;
            }
            if (total <= 17.2) {
                return 21 + (total - 0f) / ((17.2f - 0f) / 20);
            }
            if (total <= 30.0) {
                return 41 + (total - 17.2f) / ((30.0f - 17.2f) / 20);
            }
            if (total <= 42.9) {
                return 61 + (total - 30.0f) / ((42.9f - 30.0f) / 20);
            }
            if (total <= 55.8) {
                return 81 + (total - 42.9f) / ((55.8f - 42.9f) / 20);
            }
            if (total <= 68.6) {
                return 81 + (total - 55.8f) / ((68.6f - 55.8f) / 20);
            }
            if (total <= 85.8) {
                return 61 + (total - 68.6f) / ((85.8f - 68.6f) / 20);
            }
            return 60;
        }
        if (june == JULY2) {
            if (total < 0) {
                return 20;
            }
            if (total <= 19.8) {
                return 21 + (total - 0f) / ((19.8f - 0f) / 20);
            }
            if (total <= 34.7) {
                return 41 + (total - 19.8f) / ((34.7f - 19.8f) / 20);
            }
            if (total <= 49.6) {
                return 61 + (total - 34.7f) / ((49.6f - 34.7f) / 20);
            }
            if (total <= 64.5) {
                return 81 + (total - 49.6f) / ((64.5f - 49.6f) / 20);
            }
            if (total <= 79.4) {
                return 81 + (total - 64.5f) / ((79.4f - 64.5f) / 20);
            }
            if (total <= 99.2) {
                return 61 + (total - 79.4f) / ((99.2f - 79.4f) / 20);
            }
            return 60;
        }
        if (june == JULY3) {
            if (total < 0) {
                return 20;
            }
            if (total <= 22.3) {
                return 21 + (total - 0) / ((22.3f - 0) / 20);
            }
            if (total <= 39.1) {
                return 41 + (total - 22.3f) / ((39.1f - 22.3f) / 20);
            }
            if (total <= 55.8) {
                return 61 + (total - 39.1f) / ((55.8f - 39.1f) / 20);
            }
            if (total <= 72.5) {
                return 81 + (total - 55.8f) / ((72.5f - 55.8f) / 20);
            }
            if (total <= 89.3) {
                return 81 + (total - 72.5f) / ((89.3f - 72.5f) / 20);
            }
            if (total <= 111.6) {
                return 61 + (total - 89.3f) / ((111.6f - 89.3f) / 20);
            }
            return 60;
        }

        if (june == JUNE_SGP) {
            if (total < 0) {
                return 20;
            }
            if (total <= 15.5) {
                return 21 + (total - 0) / ((22.3f - 0) / 20);
            }
            if (total <= 46.6) {
                return 41 + (total - 15.5f) / ((46.6f - 15.5f) / 20);
            }
            if (total <= 77.7) {
                return 61 + (total - 46.6f) / ((77.7f - 46.6f) / 20);
            }
            if (total <= 108.8) {
                return 81 + (total - 77.7f) / ((108.8f - 77.7f) / 20);
            }
            if (total <= 139.9) {
                return 81 + (total - 108.8f) / ((139.9f - 108.8f) / 20);
            }
            if (total <= 155.4) {
                return 61 + (total - 139.9f) / ((155.4f - 139.9f) / 20);
            }
            return 60;
        }

        if (june == JULY_SGP1) {
            if (total < 0) {
                return 20;
            }
            if (total <= 18.5) {
                return 21 + (total - 0) / ((18.5f - 0) / 20);
            }
            if (total <= 55.5) {
                return 41 + (total - 18.5f) / ((55.5f - 18.5f) / 20);
            }
            if (total <= 92.5) {
                return 61 + (total - 55.5f) / ((92.5f - 55.5f) / 20);
            }
            if (total <= 129.5) {
                return 81 + (total - 92.5f) / ((129.5f - 92.5f) / 20);
            }
            if (total <= 166.5) {
                return 81 + (total - 129.5f) / ((166.5f - 129.5f) / 20);
            }
            if (total <= 185.0) {
                return 61 + (total - 166.5f) / ((185.0f - 166.5f) / 20);
            }
            return 60;
        }

        if (june == JULY_SGP2) {
            if (total < 0) {
                return 20;
            }
            if (total <= 21.1) {
                return 21 + (total - 0) / ((21.1f - 0) / 20);
            }
            if (total <= 63.2) {
                return 41 + (total - 21.1f) / ((63.2f - 21.1f) / 20);
            }
            if (total <= 105.4) {
                return 61 + (total - 63.2f) / ((105.4f - 63.2f) / 20);
            }
            if (total <= 147.6) {
                return 81 + (total - 105.4f) / ((147.6f - 105.4f) / 20);
            }
            if (total <= 189.7) {
                return 81 + (total - 147.6f) / ((189.7f - 147.6f) / 20);
            }
            if (total <= 210.8) {
                return 61 + (total - 189.7f) / ((210.8f - 189.7f) / 20);
            }
            return 60;
        }

        if (june == AUG_SGP) {
            if (total < 0) {
                return 20;
            }
            if (total <= 20.4) {
                return 21 + (total - 0) / ((20.4f - 0) / 20);
            }
            if (total <= 61.3) {
                return 41 + (total - 20.4f) / ((61.3f - 20.4f) / 20);
            }
            if (total <= 102.1) {
                return 61 + (total - 61.3f) / ((102.1f - 61.3f) / 20);
            }
            if (total <= 142.9) {
                return 81 + (total - 102.1f) / ((142.9f - 102.1f) / 20);
            }
            if (total <= 183.8) {
                return 81 + (total - 142.9f) / ((183.8f - 142.9f) / 20);
            }
            if (total <= 204.2) {
                return 61 + (total - 183.8f) / ((204.2f - 183.8f) / 20);
            }
            return 60;
        }

        return 0;
    }

    /**
     * 计算温度适宜度等级
     *
     * @param dataList
     * @param dj
     * @param model
     * @return
     */
    private static float calcAvgTemp(List<String> dataList, int dj, Model model) {
        float total = 0;
        for (String tmp : dataList) {
            total += Float.parseFloat(tmp.split(",")[0]);
        }
        float temp = total / dataList.size();
        if (dj == DJ) {
            if (temp < -14.5) {
                return 20;
            }
            if (temp <= -12.4) {
                return 21 + (temp + 14.5f) / ((-12.5f + 14.5f) / 20);
            }
            if (temp <= -11.6) {
                return 41 + (temp + 12.4f) / ((-11.6f + 12.4f) / 20);
            }
            if (temp <= -9.3) {
                return 61 + (temp + 11.6f) / ((-9.3f + 11.6f) / 20);
            }
            return 100;
        } else {
            if (temp > 17) {
                return 20;
            }
            if (temp >= 16.1) {
                return 21 + (temp - 16.1f) / ((17f - 16.1f) / 20);
            }
            if (temp >= 15.5) {
                return 41 + (temp - 15.5f) / ((16f - 15.5f) / 20);
            }
            if (temp >= 14.3) {
                return 61 + (temp - 14.3f) / ((15.4f - 14.3f) / 20);
            }
            return 100;
        }

    }

    /**
     * 数据分类处理，根据时间将数据分类 TMP,TMAX,RAIN,RH
     *
     * @param djData
     * @param mayData
     * @param june1Data
     * @param june2Data
     * @param june3Data
     * @param july1Data
     * @param july2Data
     * @param july3Data
     * @param aug1Data
     * @param stationDatas
     */
    private static void assistData(List<String> djData, List<String> mayData, List<String> june1Data, List<String> june2Data, List<String> june3Data, List<String> july1Data, List<String> july2Data, List<String> july3Data, List<String> aug1Data, List<StationData> stationDatas) throws ParseException {
        for (int i = 0; i < stationDatas.size(); i++) {
            StationData data = stationDatas.get(i);
            int month = DateCalculator.getInstance().getMonth(data.getDate(), "yyyy-MM-dd");
            int day = DateCalculator.getInstance().getDay(data.getDate(), "yyyy-MM-dd");
            if (month == 5) {
                mayData.add(data.getTemp() + "," + data.getMaxTemp() + "," + data.getRain() + "," + data.getHumidity());
            } else if (month == 6) {
                setMonthData(june1Data, june2Data, june3Data, data, day);
            } else if (month == 7) {
                setMonthData(july1Data, july2Data, july3Data, data, day);
            } else if (month == 8) {
                if (day <= 10) {
                    aug1Data.add(data.getTemp() + "," + data.getMaxTemp() + "," + data.getRain() + "," + data.getHumidity());
                }
            } else if (month >= 11 || (month >= 1 && month <= 2)) {
                djData.add(data.getTemp() + "," + data.getMaxTemp() + "," + data.getRain() + "," + data.getHumidity());
            }
        }
    }

    /**
     * 数据分类处理，按照上中下旬将数据分类
     *
     * @param month1Data 上旬数据
     * @param month2Data 中旬数据
     * @param month3Data 下旬数据
     * @param data       站点数据
     * @param day        数据时间（天）
     */
    private static void setMonthData(List<String> month1Data, List<String> month2Data, List<String> month3Data, StationData data, int day) {
        if (day <= 10) {
            month1Data.add(data.getTemp() + "," + data.getMaxTemp() + "," + data.getRain() + "," + data.getHumidity());
        } else if (day <= 20) {
            month2Data.add(data.getTemp() + "," + data.getMaxTemp() + "," + data.getRain() + "," + data.getHumidity());
        } else {
            month3Data.add(data.getTemp() + "," + data.getMaxTemp() + "," + data.getRain() + "," + data.getHumidity());
        }
    }

}
